Importing Libraries¶

In [1]:
import os
import shutil
import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
import random
import plotly.express as px
import cv2 as cv2
import scipy as sp

from shutil import copyfile
from tensorflow.keras.layers import Conv2D,Add,MaxPooling2D, Dense, BatchNormalization,Input,Flatten, Dropout
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import LearningRateScheduler
from tensorflow.keras.preprocessing.image import ImageDataGenerator 
In [2]:
source_path = 'C:/Users/alasmar/Downloads/cats-vs-dogs/PetImages'
source_path_cats = os.path.join(source_path, 'Cat')

source_path_dogs = os.path.join(source_path, 'Dog')


# os.listdir returns a list containing all files under the given path
print(f"There are {len(os.listdir(source_path_dogs))} images of dogs.")
print(f"There are {len(os.listdir(source_path_cats))} images of cats.")
There are 12501 images of dogs.
There are 12501 images of cats.

Data Preprocessing¶

In [3]:
#Define data path
CAT_DIR = 'C:/Users/alasmar/Downloads/cats-vs-dogs/PetImages/Cat'
DOG_DIR = 'C:/Users/alasmar/Downloads/cats-vs-dogs/PetImages/Dog'

try:
    os.mkdir('C:/Users/alasmar/Downloads/cats-v-dogs')
    os.mkdir('C:/Users/alasmar/Downloads/cats-v-dogs/training')
    os.mkdir('C:/Users/alasmar/Downloads/cats-v-dogs/validation')
    os.mkdir('C:/Users/alasmar/Downloads/cats-v-dogs/training/cats')
    os.mkdir('C:/Users/alasmar/Downloads/cats-v-dogs/training/dogs')
    os.mkdir('C:/Users/alasmar/Downloads/cats-v-dogs/validation/cats')
    os.mkdir('C:/Users/alasmar/Downloads/cats-v-dogs/validation/dogs')
except OSError:
    print('Error failed to make directory')
Let's check the distribution of the data¶
In [4]:
class_names = ['Cat', 'Dog'] 

n_cats = len(os.listdir('C:/Users/alasmar/Downloads/cats-vs-dogs/PetImages/Cat'))

n_dogs = len(os.listdir('C:/Users/alasmar/Downloads/cats-vs-dogs/PetImages/Dog'))
n_images = [n_cats, n_dogs]
px.pie(names=class_names, values=n_images)
Now let's create directories for training and validation¶
In [5]:
TRAINING_DIR = "C:/Users/alasmar/Downloads/cats-v-dogs/training/"
VALIDATION_DIR = "C:/Users/alasmar/Downloads/cats-v-dogs/validation/"

TRAINING_CATS = os.path.join(TRAINING_DIR, "cats/")
VALIDATION_CATS = os.path.join(VALIDATION_DIR, "cats/")

TRAINING_DOGS = os.path.join(TRAINING_DIR, "dogs/")
VALIDATION_DOGS = os.path.join(VALIDATION_DIR, "dogs/")

# Define whether to include test split or not
INCLUDE_TEST = True
The data is perfectly balanced¶
Now let's create a function to split the data¶
In [6]:
def split_data(main_dir, training_dir, validation_dir, split_size):
    """
    Splits the data into train and test sets

    Args:
    main_dir (string):  path containing the images
    training_dir (string):  path to be used for training
    validation_dir (string):  path to be used for validation
    split_size (float): size of the dataset to be used for training
    """
    files = []
    for file in os.listdir(main_dir):
        if  os.path.getsize(os.path.join(main_dir, file)): # check if the file's size isn't 0
            files.append(file) # appends file name to a list

    shuffled_files = random.sample(files,  len(files)) # shuffles the data
    split = int(0.9 * len(shuffled_files)) #the training split casted into int for numeric rounding

    train = shuffled_files[:split] #training split
    validation = shuffled_files[split:] # validation split

    for element in train:
        copyfile(os.path.join(main_dir,  element), os.path.join(training_dir, element)) # copy files into training directory

    for element in validation:
        copyfile(os.path.join(main_dir,  element), os.path.join(validation_dir, element))# copy files into validation directory
Now let's call the function to create the training/validation data¶
In [7]:
split_data(CAT_DIR,'C:/Users/alasmar/Downloads/cats-v-dogs/training/cats','C:/Users/alasmar/Downloads/cats-v-dogs/validation/cats', 0.9)
In [8]:
split_data(DOG_DIR, 'C:/Users/alasmar/Downloads/cats-v-dogs/training/dogs','C:/Users/alasmar/Downloads/cats-v-dogs/validation/dogs', 0.9)

Create Generators¶

In [9]:
train_gen = ImageDataGenerator(
        rescale=1./255)


validation_gen =  ImageDataGenerator(
        rescale=1./255.)

if INCLUDE_TEST:
    test_gen =  ImageDataGenerator(
            rescale=1./255.)
In [10]:
train_generator = train_gen.flow_from_directory(
        'C:/Users/alasmar/Downloads/cats-v-dogs/training',
        target_size=(150, 150),
        batch_size=64,
        class_mode='binary')
validation_generator = validation_gen.flow_from_directory(
        'C:/Users/alasmar/Downloads/cats-v-dogs/validation',
        target_size=(150, 150),
        batch_size=64,
        class_mode='binary')

if INCLUDE_TEST:
    test_generator = test_gen.flow_from_directory(
        'C:/Users/alasmar/Downloads/cats-v-dogs/validation',
        target_size=(150, 150),
        batch_size=64,
        class_mode='binary')
Found 22498 images belonging to 2 classes.
Found 2500 images belonging to 2 classes.
Found 2500 images belonging to 2 classes.
Now let's visualize the data¶
In [11]:
def plot_data(generator, n_images):
    """
    Plots random data from dataset
    Args:
    generator: a generator instance
    n_images : number of images to plot
    """
    i = 1
    images, labels = generator.next()
    labels = labels.astype('int32')

    plt.figure(figsize=(14, 15))
    
    for image, label in zip(images, labels):
        plt.subplot(4, 3, i)
        plt.imshow(image)
        plt.title(class_names[label])
        plt.axis('off')
        i += 1
        if i == n_images:
            break
    
    plt.show()
In [12]:
plot_data(train_generator,7)
In [13]:
plot_data(validation_generator,7)
In [14]:
if INCLUDE_TEST:
    plot_data(test_generator, 10)
Great, now that the data is ready let's train our model¶

Model Implementations¶

In [15]:
inputs = tf.keras.layers.Input(shape=(150,150,3))
x =  tf.keras.layers.Conv2D(32, (3,3), activation='relu')(inputs)
x = tf.keras.layers.Conv2D(64, (3,3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D(2,2)(x)

x = tf.keras.layers.Conv2D(64, (3,3), activation='relu')(x)
x = tf.keras.layers.Conv2D(128, (3,3), activation='relu')(x)
x = tf.keras.layers.MaxPooling2D(2,2)(x)

x = tf.keras.layers.Conv2D(128, (3,3), activation='relu')(x)
x = tf.keras.layers.Conv2D(256, (3,3), activation='relu')(x)
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = Dense(1024,activation='relu')(x)
x = tf.keras.layers.Dense(2, activation='softmax')(x) 

model = Model(inputs=inputs, outputs=x)
In [16]:
model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=0.001),
              loss='sparse_categorical_crossentropy',
              metrics = ['accuracy'])
In [17]:
r = model.fit(
        train_generator,
        epochs=5,
        validation_data=validation_generator)
Epoch 1/5
280/352 [======================>.......] - ETA: 8:16 - loss: 0.6898 - accuracy: 0.5618
C:\Users\alasmar\AppData\Local\Programs\Python\Python310\lib\site-packages\PIL\TiffImagePlugin.py:845: UserWarning:

Truncated File Read

352/352 [==============================] - 2468s 7s/step - loss: 0.6852 - accuracy: 0.5720 - val_loss: 0.6539 - val_accuracy: 0.6348
Epoch 2/5
352/352 [==============================] - 1943s 6s/step - loss: 0.6359 - accuracy: 0.6502 - val_loss: 0.6414 - val_accuracy: 0.6252
Epoch 3/5
352/352 [==============================] - 1886s 5s/step - loss: 0.5943 - accuracy: 0.6882 - val_loss: 0.5499 - val_accuracy: 0.7372
Epoch 4/5
352/352 [==============================] - 1795s 5s/step - loss: 0.5525 - accuracy: 0.7308 - val_loss: 0.6257 - val_accuracy: 0.6524
Epoch 5/5
352/352 [==============================] - 1906s 5s/step - loss: 0.5240 - accuracy: 0.7478 - val_loss: 0.4896 - val_accuracy: 0.7544

Model Evaluation¶

Evaluate the model on the test set¶
In [22]:
if INCLUDE_TEST:
    model.evaluate(test_generator)
40/40 [==============================] - 50s 1s/step - loss: 0.4896 - accuracy: 0.7544

Visualize the predicitons¶

In [23]:
def plot_prediction(generator, n_images):
    """
    Test the model on random predictions
    Args:
    generator: a generator instance
    n_images : number of images to plot

    """
    i = 1
    # Get the images and the labels from the generator
    images, labels = generator.next()
    # Gets the model predictions
    preds = model.predict(images)
    predictions = np.argmax(preds, axis=1)
    labels = labels.astype('int32')
    plt.figure(figsize=(14, 15))
    for image, label in zip(images, labels):
        plt.subplot(4, 3, i)
        plt.imshow(image)
        if predictions[i] == labels[i]:
            title_obj = plt.title(class_names[label])
            plt.setp(title_obj, color='g') 
            plt.axis('off')
        else:
            title_obj = plt.title(class_names[label])
            plt.setp(title_obj, color='r') 
            plt.axis('off')
        i += 1
        if i == n_images:
            break
    
    plt.show()
In [24]:
if INCLUDE_TEST:
    plot_prediction(test_generator, 10)
2/2 [==============================] - 1s 604ms/step
In [25]:
plot_prediction(validation_generator, 10)
2/2 [==============================] - 1s 599ms/step

Visualize the activation maps¶

In [27]:
# Create a  model to visualize activation maps
gp_weights =  model.get_layer('dense').get_weights()[0]
activation_model = Model(model.inputs, outputs=(model.get_layer('conv2d_5').output, model.get_layer('dense_1').output))
In [28]:
# Use the model to make predictions on the test generator
images, _ = test_generator.next()
features, results = activation_model.predict(images)
2/2 [==============================] - 1s 574ms/step
In [29]:
def show_cam(image_index, features, results):
    """
    Shows activation maps
    Args:
    image_index: index of image
    features: the extracted features
    results: model's predictions
    """
    # takes the features of the chosen image
    features_for_img = features[image_index,:,:,:]

    # get the class with the highest output probability
    prediction = np.argmax(results[image_index])

    # get the gap weights at the predicted class
    class_activation_weights = gp_weights[:,prediction]

    # upsample the features to the image's original size (150 x 150)
    class_activation_features = sp.ndimage.zoom(features_for_img, (150/30, 150/30, 1), order=2)

    # compute the intensity of each feature in the CAM
    cam_output  = np.dot(class_activation_features,class_activation_weights)

    print('Predicted Class = ' +str(class_names[prediction])+ ', Probability = ' + str(results[image_index][prediction]))

    # show the upsampled image
    
    plt.imshow(images[image_index])

    # strongly classified (95% probability) images will be in green, else red
    if results[image_index][prediction]>0.95:
        cmap_str = 'Greens'
    else:
        cmap_str = 'Blues'

    # overlay the cam output
    plt.imshow(cam_output, cmap=cmap_str, alpha=0.5)

    # display the image
    plt.show()
In [30]:
def show_maps(desired_class, num_maps):
    '''
    goes through the first 10,000 test images and generates Cam activation maps
    Args:
    desired_class: class to show the maps for
    num_maps: number of maps to be generated 
    '''
    counter = 0
    # go through the first 10000 images
    for i in range(0,10000):
        # break if we already displayed the specified number of maps
        if counter == num_maps:
            break

        # images that match the class will be shown
        if np.argmax(results[i]) == desired_class:
            counter += 1
            show_cam(i,features, results)
In [31]:
show_maps(desired_class=1, num_maps=5)
Predicted Class = Dog, Probability = 0.5200827
Predicted Class = Dog, Probability = 0.6769477
Predicted Class = Dog, Probability = 0.9477724
Predicted Class = Dog, Probability = 0.8664233
Predicted Class = Dog, Probability = 0.5737325
In [32]:
show_maps(desired_class=0, num_maps=5)
Predicted Class = Cat, Probability = 0.65568477
Predicted Class = Cat, Probability = 0.78922504
Predicted Class = Cat, Probability = 0.8550956
Predicted Class = Cat, Probability = 0.9108136
Predicted Class = Cat, Probability = 0.73102206

Visualize training process¶

In [33]:
results = pd.DataFrame(r.history)
results.tail()
Out[33]:
loss accuracy val_loss val_accuracy
0 0.685154 0.571962 0.653850 0.6348
1 0.635894 0.650191 0.641383 0.6252
2 0.594305 0.688239 0.549863 0.7372
3 0.552515 0.730776 0.625722 0.6524
4 0.524021 0.747755 0.489643 0.7544
In [34]:
fig = px.line(results,y=[results['accuracy'],results['val_accuracy']],template="seaborn",color_discrete_sequence=['#fad25a','red'])
fig.update_layout(   
    title_font_color="#fad25a", 
    xaxis=dict(color="#fad25a",title='Epochs'), 
    yaxis=dict(color="#fad25a")
 )
fig.show()
In [35]:
fig = px.line(results,y=[results['loss'],results['val_loss']],template="seaborn",color_discrete_sequence=['#fad25a','red'])
fig.update_layout(   
    title_font_color="#fad25a", 
    xaxis=dict(color="#fad25a",title='Epochs'), 
    yaxis=dict(color="#fad25a")
 )
fig.show()

We'll be using InceptionV3¶

In [36]:
train_datagen = ImageDataGenerator(rescale = 1./255.,
                                   rotation_range = 40,
                                   width_shift_range = 0.2,
                                   height_shift_range = 0.2,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True)


valid_datagen = ImageDataGenerator( rescale = 1.0/255. )
# Flow training images in batches of 20 using train_datagen generator
train_generator = train_datagen.flow_from_directory('C:/Users/alasmar/Downloads/cats-v-dogs/training',
                                                    batch_size = 64,
                                                    class_mode = 'binary', 
                                                    target_size = (150, 150))     


validation_generator =  valid_datagen.flow_from_directory( 'C:/Users/alasmar/Downloads/cats-v-dogs/validation',
                                                          batch_size  = 64,
                                                          class_mode  = 'binary', 
                                                          target_size = (150, 150))
Found 22498 images belonging to 2 classes.
Found 2500 images belonging to 2 classes.
In [37]:
test_gen =  ImageDataGenerator(
            rescale=1./255.)
test_generator = test_gen.flow_from_directory(
        'C:/Users/alasmar/Downloads/cats-v-dogs/validation',
        target_size=(150, 150),
        batch_size=64,
        class_mode='binary')
Found 2500 images belonging to 2 classes.
In [38]:
#Load Model
inception = tf.keras.applications.InceptionV3(weights='imagenet',include_top=False,input_shape=(150,150,3))

for layer in inception.layers[:-10]:
    layer.trainable = False # Freeze weights of all layers till except the last 10
    
last_layer = inception.get_layer('mixed7')

print('last layer output shape: ', last_layer.output_shape)

layer_output = last_layer.output
last layer output shape:  (None, 7, 7, 768)
In [39]:
x = Flatten()(layer_output)
x = BatchNormalization()(x)
x = Dense(1024, activation='relu')(x)
x = Dropout(0.2)(x)
predictions = Dense(2, activation='softmax')(x)
model = Model(inception.input, predictions)
model.summary()
Model: "model_2"
__________________________________________________________________________________________________
 Layer (type)                   Output Shape         Param #     Connected to                     
==================================================================================================
 input_2 (InputLayer)           [(None, 150, 150, 3  0           []                               
                                )]                                                                
                                                                                                  
 conv2d_6 (Conv2D)              (None, 74, 74, 32)   864         ['input_2[0][0]']                
                                                                                                  
 batch_normalization (BatchNorm  (None, 74, 74, 32)  96          ['conv2d_6[0][0]']               
 alization)                                                                                       
                                                                                                  
 activation (Activation)        (None, 74, 74, 32)   0           ['batch_normalization[0][0]']    
                                                                                                  
 conv2d_7 (Conv2D)              (None, 72, 72, 32)   9216        ['activation[0][0]']             
                                                                                                  
 batch_normalization_1 (BatchNo  (None, 72, 72, 32)  96          ['conv2d_7[0][0]']               
 rmalization)                                                                                     
                                                                                                  
 activation_1 (Activation)      (None, 72, 72, 32)   0           ['batch_normalization_1[0][0]']  
                                                                                                  
 conv2d_8 (Conv2D)              (None, 72, 72, 64)   18432       ['activation_1[0][0]']           
                                                                                                  
 batch_normalization_2 (BatchNo  (None, 72, 72, 64)  192         ['conv2d_8[0][0]']               
 rmalization)                                                                                     
                                                                                                  
 activation_2 (Activation)      (None, 72, 72, 64)   0           ['batch_normalization_2[0][0]']  
                                                                                                  
 max_pooling2d_2 (MaxPooling2D)  (None, 35, 35, 64)  0           ['activation_2[0][0]']           
                                                                                                  
 conv2d_9 (Conv2D)              (None, 35, 35, 80)   5120        ['max_pooling2d_2[0][0]']        
                                                                                                  
 batch_normalization_3 (BatchNo  (None, 35, 35, 80)  240         ['conv2d_9[0][0]']               
 rmalization)                                                                                     
                                                                                                  
 activation_3 (Activation)      (None, 35, 35, 80)   0           ['batch_normalization_3[0][0]']  
                                                                                                  
 conv2d_10 (Conv2D)             (None, 33, 33, 192)  138240      ['activation_3[0][0]']           
                                                                                                  
 batch_normalization_4 (BatchNo  (None, 33, 33, 192)  576        ['conv2d_10[0][0]']              
 rmalization)                                                                                     
                                                                                                  
 activation_4 (Activation)      (None, 33, 33, 192)  0           ['batch_normalization_4[0][0]']  
                                                                                                  
 max_pooling2d_3 (MaxPooling2D)  (None, 16, 16, 192)  0          ['activation_4[0][0]']           
                                                                                                  
 conv2d_14 (Conv2D)             (None, 16, 16, 64)   12288       ['max_pooling2d_3[0][0]']        
                                                                                                  
 batch_normalization_8 (BatchNo  (None, 16, 16, 64)  192         ['conv2d_14[0][0]']              
 rmalization)                                                                                     
                                                                                                  
 activation_8 (Activation)      (None, 16, 16, 64)   0           ['batch_normalization_8[0][0]']  
                                                                                                  
 conv2d_12 (Conv2D)             (None, 16, 16, 48)   9216        ['max_pooling2d_3[0][0]']        
                                                                                                  
 conv2d_15 (Conv2D)             (None, 16, 16, 96)   55296       ['activation_8[0][0]']           
                                                                                                  
 batch_normalization_6 (BatchNo  (None, 16, 16, 48)  144         ['conv2d_12[0][0]']              
 rmalization)                                                                                     
                                                                                                  
 batch_normalization_9 (BatchNo  (None, 16, 16, 96)  288         ['conv2d_15[0][0]']              
 rmalization)                                                                                     
                                                                                                  
 activation_6 (Activation)      (None, 16, 16, 48)   0           ['batch_normalization_6[0][0]']  
                                                                                                  
 activation_9 (Activation)      (None, 16, 16, 96)   0           ['batch_normalization_9[0][0]']  
                                                                                                  
 average_pooling2d (AveragePool  (None, 16, 16, 192)  0          ['max_pooling2d_3[0][0]']        
 ing2D)                                                                                           
                                                                                                  
 conv2d_11 (Conv2D)             (None, 16, 16, 64)   12288       ['max_pooling2d_3[0][0]']        
                                                                                                  
 conv2d_13 (Conv2D)             (None, 16, 16, 64)   76800       ['activation_6[0][0]']           
                                                                                                  
 conv2d_16 (Conv2D)             (None, 16, 16, 96)   82944       ['activation_9[0][0]']           
                                                                                                  
 conv2d_17 (Conv2D)             (None, 16, 16, 32)   6144        ['average_pooling2d[0][0]']      
                                                                                                  
 batch_normalization_5 (BatchNo  (None, 16, 16, 64)  192         ['conv2d_11[0][0]']              
 rmalization)                                                                                     
                                                                                                  
 batch_normalization_7 (BatchNo  (None, 16, 16, 64)  192         ['conv2d_13[0][0]']              
 rmalization)                                                                                     
                                                                                                  
 batch_normalization_10 (BatchN  (None, 16, 16, 96)  288         ['conv2d_16[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_11 (BatchN  (None, 16, 16, 32)  96          ['conv2d_17[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_5 (Activation)      (None, 16, 16, 64)   0           ['batch_normalization_5[0][0]']  
                                                                                                  
 activation_7 (Activation)      (None, 16, 16, 64)   0           ['batch_normalization_7[0][0]']  
                                                                                                  
 activation_10 (Activation)     (None, 16, 16, 96)   0           ['batch_normalization_10[0][0]'] 
                                                                                                  
 activation_11 (Activation)     (None, 16, 16, 32)   0           ['batch_normalization_11[0][0]'] 
                                                                                                  
 mixed0 (Concatenate)           (None, 16, 16, 256)  0           ['activation_5[0][0]',           
                                                                  'activation_7[0][0]',           
                                                                  'activation_10[0][0]',          
                                                                  'activation_11[0][0]']          
                                                                                                  
 conv2d_21 (Conv2D)             (None, 16, 16, 64)   16384       ['mixed0[0][0]']                 
                                                                                                  
 batch_normalization_15 (BatchN  (None, 16, 16, 64)  192         ['conv2d_21[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_15 (Activation)     (None, 16, 16, 64)   0           ['batch_normalization_15[0][0]'] 
                                                                                                  
 conv2d_19 (Conv2D)             (None, 16, 16, 48)   12288       ['mixed0[0][0]']                 
                                                                                                  
 conv2d_22 (Conv2D)             (None, 16, 16, 96)   55296       ['activation_15[0][0]']          
                                                                                                  
 batch_normalization_13 (BatchN  (None, 16, 16, 48)  144         ['conv2d_19[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_16 (BatchN  (None, 16, 16, 96)  288         ['conv2d_22[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_13 (Activation)     (None, 16, 16, 48)   0           ['batch_normalization_13[0][0]'] 
                                                                                                  
 activation_16 (Activation)     (None, 16, 16, 96)   0           ['batch_normalization_16[0][0]'] 
                                                                                                  
 average_pooling2d_1 (AveragePo  (None, 16, 16, 256)  0          ['mixed0[0][0]']                 
 oling2D)                                                                                         
                                                                                                  
 conv2d_18 (Conv2D)             (None, 16, 16, 64)   16384       ['mixed0[0][0]']                 
                                                                                                  
 conv2d_20 (Conv2D)             (None, 16, 16, 64)   76800       ['activation_13[0][0]']          
                                                                                                  
 conv2d_23 (Conv2D)             (None, 16, 16, 96)   82944       ['activation_16[0][0]']          
                                                                                                  
 conv2d_24 (Conv2D)             (None, 16, 16, 64)   16384       ['average_pooling2d_1[0][0]']    
                                                                                                  
 batch_normalization_12 (BatchN  (None, 16, 16, 64)  192         ['conv2d_18[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_14 (BatchN  (None, 16, 16, 64)  192         ['conv2d_20[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_17 (BatchN  (None, 16, 16, 96)  288         ['conv2d_23[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_18 (BatchN  (None, 16, 16, 64)  192         ['conv2d_24[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_12 (Activation)     (None, 16, 16, 64)   0           ['batch_normalization_12[0][0]'] 
                                                                                                  
 activation_14 (Activation)     (None, 16, 16, 64)   0           ['batch_normalization_14[0][0]'] 
                                                                                                  
 activation_17 (Activation)     (None, 16, 16, 96)   0           ['batch_normalization_17[0][0]'] 
                                                                                                  
 activation_18 (Activation)     (None, 16, 16, 64)   0           ['batch_normalization_18[0][0]'] 
                                                                                                  
 mixed1 (Concatenate)           (None, 16, 16, 288)  0           ['activation_12[0][0]',          
                                                                  'activation_14[0][0]',          
                                                                  'activation_17[0][0]',          
                                                                  'activation_18[0][0]']          
                                                                                                  
 conv2d_28 (Conv2D)             (None, 16, 16, 64)   18432       ['mixed1[0][0]']                 
                                                                                                  
 batch_normalization_22 (BatchN  (None, 16, 16, 64)  192         ['conv2d_28[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_22 (Activation)     (None, 16, 16, 64)   0           ['batch_normalization_22[0][0]'] 
                                                                                                  
 conv2d_26 (Conv2D)             (None, 16, 16, 48)   13824       ['mixed1[0][0]']                 
                                                                                                  
 conv2d_29 (Conv2D)             (None, 16, 16, 96)   55296       ['activation_22[0][0]']          
                                                                                                  
 batch_normalization_20 (BatchN  (None, 16, 16, 48)  144         ['conv2d_26[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_23 (BatchN  (None, 16, 16, 96)  288         ['conv2d_29[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_20 (Activation)     (None, 16, 16, 48)   0           ['batch_normalization_20[0][0]'] 
                                                                                                  
 activation_23 (Activation)     (None, 16, 16, 96)   0           ['batch_normalization_23[0][0]'] 
                                                                                                  
 average_pooling2d_2 (AveragePo  (None, 16, 16, 288)  0          ['mixed1[0][0]']                 
 oling2D)                                                                                         
                                                                                                  
 conv2d_25 (Conv2D)             (None, 16, 16, 64)   18432       ['mixed1[0][0]']                 
                                                                                                  
 conv2d_27 (Conv2D)             (None, 16, 16, 64)   76800       ['activation_20[0][0]']          
                                                                                                  
 conv2d_30 (Conv2D)             (None, 16, 16, 96)   82944       ['activation_23[0][0]']          
                                                                                                  
 conv2d_31 (Conv2D)             (None, 16, 16, 64)   18432       ['average_pooling2d_2[0][0]']    
                                                                                                  
 batch_normalization_19 (BatchN  (None, 16, 16, 64)  192         ['conv2d_25[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_21 (BatchN  (None, 16, 16, 64)  192         ['conv2d_27[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_24 (BatchN  (None, 16, 16, 96)  288         ['conv2d_30[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_25 (BatchN  (None, 16, 16, 64)  192         ['conv2d_31[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_19 (Activation)     (None, 16, 16, 64)   0           ['batch_normalization_19[0][0]'] 
                                                                                                  
 activation_21 (Activation)     (None, 16, 16, 64)   0           ['batch_normalization_21[0][0]'] 
                                                                                                  
 activation_24 (Activation)     (None, 16, 16, 96)   0           ['batch_normalization_24[0][0]'] 
                                                                                                  
 activation_25 (Activation)     (None, 16, 16, 64)   0           ['batch_normalization_25[0][0]'] 
                                                                                                  
 mixed2 (Concatenate)           (None, 16, 16, 288)  0           ['activation_19[0][0]',          
                                                                  'activation_21[0][0]',          
                                                                  'activation_24[0][0]',          
                                                                  'activation_25[0][0]']          
                                                                                                  
 conv2d_33 (Conv2D)             (None, 16, 16, 64)   18432       ['mixed2[0][0]']                 
                                                                                                  
 batch_normalization_27 (BatchN  (None, 16, 16, 64)  192         ['conv2d_33[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_27 (Activation)     (None, 16, 16, 64)   0           ['batch_normalization_27[0][0]'] 
                                                                                                  
 conv2d_34 (Conv2D)             (None, 16, 16, 96)   55296       ['activation_27[0][0]']          
                                                                                                  
 batch_normalization_28 (BatchN  (None, 16, 16, 96)  288         ['conv2d_34[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_28 (Activation)     (None, 16, 16, 96)   0           ['batch_normalization_28[0][0]'] 
                                                                                                  
 conv2d_32 (Conv2D)             (None, 7, 7, 384)    995328      ['mixed2[0][0]']                 
                                                                                                  
 conv2d_35 (Conv2D)             (None, 7, 7, 96)     82944       ['activation_28[0][0]']          
                                                                                                  
 batch_normalization_26 (BatchN  (None, 7, 7, 384)   1152        ['conv2d_32[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_29 (BatchN  (None, 7, 7, 96)    288         ['conv2d_35[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_26 (Activation)     (None, 7, 7, 384)    0           ['batch_normalization_26[0][0]'] 
                                                                                                  
 activation_29 (Activation)     (None, 7, 7, 96)     0           ['batch_normalization_29[0][0]'] 
                                                                                                  
 max_pooling2d_4 (MaxPooling2D)  (None, 7, 7, 288)   0           ['mixed2[0][0]']                 
                                                                                                  
 mixed3 (Concatenate)           (None, 7, 7, 768)    0           ['activation_26[0][0]',          
                                                                  'activation_29[0][0]',          
                                                                  'max_pooling2d_4[0][0]']        
                                                                                                  
 conv2d_40 (Conv2D)             (None, 7, 7, 128)    98304       ['mixed3[0][0]']                 
                                                                                                  
 batch_normalization_34 (BatchN  (None, 7, 7, 128)   384         ['conv2d_40[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_34 (Activation)     (None, 7, 7, 128)    0           ['batch_normalization_34[0][0]'] 
                                                                                                  
 conv2d_41 (Conv2D)             (None, 7, 7, 128)    114688      ['activation_34[0][0]']          
                                                                                                  
 batch_normalization_35 (BatchN  (None, 7, 7, 128)   384         ['conv2d_41[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_35 (Activation)     (None, 7, 7, 128)    0           ['batch_normalization_35[0][0]'] 
                                                                                                  
 conv2d_37 (Conv2D)             (None, 7, 7, 128)    98304       ['mixed3[0][0]']                 
                                                                                                  
 conv2d_42 (Conv2D)             (None, 7, 7, 128)    114688      ['activation_35[0][0]']          
                                                                                                  
 batch_normalization_31 (BatchN  (None, 7, 7, 128)   384         ['conv2d_37[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_36 (BatchN  (None, 7, 7, 128)   384         ['conv2d_42[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_31 (Activation)     (None, 7, 7, 128)    0           ['batch_normalization_31[0][0]'] 
                                                                                                  
 activation_36 (Activation)     (None, 7, 7, 128)    0           ['batch_normalization_36[0][0]'] 
                                                                                                  
 conv2d_38 (Conv2D)             (None, 7, 7, 128)    114688      ['activation_31[0][0]']          
                                                                                                  
 conv2d_43 (Conv2D)             (None, 7, 7, 128)    114688      ['activation_36[0][0]']          
                                                                                                  
 batch_normalization_32 (BatchN  (None, 7, 7, 128)   384         ['conv2d_38[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_37 (BatchN  (None, 7, 7, 128)   384         ['conv2d_43[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_32 (Activation)     (None, 7, 7, 128)    0           ['batch_normalization_32[0][0]'] 
                                                                                                  
 activation_37 (Activation)     (None, 7, 7, 128)    0           ['batch_normalization_37[0][0]'] 
                                                                                                  
 average_pooling2d_3 (AveragePo  (None, 7, 7, 768)   0           ['mixed3[0][0]']                 
 oling2D)                                                                                         
                                                                                                  
 conv2d_36 (Conv2D)             (None, 7, 7, 192)    147456      ['mixed3[0][0]']                 
                                                                                                  
 conv2d_39 (Conv2D)             (None, 7, 7, 192)    172032      ['activation_32[0][0]']          
                                                                                                  
 conv2d_44 (Conv2D)             (None, 7, 7, 192)    172032      ['activation_37[0][0]']          
                                                                                                  
 conv2d_45 (Conv2D)             (None, 7, 7, 192)    147456      ['average_pooling2d_3[0][0]']    
                                                                                                  
 batch_normalization_30 (BatchN  (None, 7, 7, 192)   576         ['conv2d_36[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_33 (BatchN  (None, 7, 7, 192)   576         ['conv2d_39[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_38 (BatchN  (None, 7, 7, 192)   576         ['conv2d_44[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_39 (BatchN  (None, 7, 7, 192)   576         ['conv2d_45[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_30 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_30[0][0]'] 
                                                                                                  
 activation_33 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_33[0][0]'] 
                                                                                                  
 activation_38 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_38[0][0]'] 
                                                                                                  
 activation_39 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_39[0][0]'] 
                                                                                                  
 mixed4 (Concatenate)           (None, 7, 7, 768)    0           ['activation_30[0][0]',          
                                                                  'activation_33[0][0]',          
                                                                  'activation_38[0][0]',          
                                                                  'activation_39[0][0]']          
                                                                                                  
 conv2d_50 (Conv2D)             (None, 7, 7, 160)    122880      ['mixed4[0][0]']                 
                                                                                                  
 batch_normalization_44 (BatchN  (None, 7, 7, 160)   480         ['conv2d_50[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_44 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_44[0][0]'] 
                                                                                                  
 conv2d_51 (Conv2D)             (None, 7, 7, 160)    179200      ['activation_44[0][0]']          
                                                                                                  
 batch_normalization_45 (BatchN  (None, 7, 7, 160)   480         ['conv2d_51[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_45 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_45[0][0]'] 
                                                                                                  
 conv2d_47 (Conv2D)             (None, 7, 7, 160)    122880      ['mixed4[0][0]']                 
                                                                                                  
 conv2d_52 (Conv2D)             (None, 7, 7, 160)    179200      ['activation_45[0][0]']          
                                                                                                  
 batch_normalization_41 (BatchN  (None, 7, 7, 160)   480         ['conv2d_47[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_46 (BatchN  (None, 7, 7, 160)   480         ['conv2d_52[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_41 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_41[0][0]'] 
                                                                                                  
 activation_46 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_46[0][0]'] 
                                                                                                  
 conv2d_48 (Conv2D)             (None, 7, 7, 160)    179200      ['activation_41[0][0]']          
                                                                                                  
 conv2d_53 (Conv2D)             (None, 7, 7, 160)    179200      ['activation_46[0][0]']          
                                                                                                  
 batch_normalization_42 (BatchN  (None, 7, 7, 160)   480         ['conv2d_48[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_47 (BatchN  (None, 7, 7, 160)   480         ['conv2d_53[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_42 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_42[0][0]'] 
                                                                                                  
 activation_47 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_47[0][0]'] 
                                                                                                  
 average_pooling2d_4 (AveragePo  (None, 7, 7, 768)   0           ['mixed4[0][0]']                 
 oling2D)                                                                                         
                                                                                                  
 conv2d_46 (Conv2D)             (None, 7, 7, 192)    147456      ['mixed4[0][0]']                 
                                                                                                  
 conv2d_49 (Conv2D)             (None, 7, 7, 192)    215040      ['activation_42[0][0]']          
                                                                                                  
 conv2d_54 (Conv2D)             (None, 7, 7, 192)    215040      ['activation_47[0][0]']          
                                                                                                  
 conv2d_55 (Conv2D)             (None, 7, 7, 192)    147456      ['average_pooling2d_4[0][0]']    
                                                                                                  
 batch_normalization_40 (BatchN  (None, 7, 7, 192)   576         ['conv2d_46[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_43 (BatchN  (None, 7, 7, 192)   576         ['conv2d_49[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_48 (BatchN  (None, 7, 7, 192)   576         ['conv2d_54[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_49 (BatchN  (None, 7, 7, 192)   576         ['conv2d_55[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_40 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_40[0][0]'] 
                                                                                                  
 activation_43 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_43[0][0]'] 
                                                                                                  
 activation_48 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_48[0][0]'] 
                                                                                                  
 activation_49 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_49[0][0]'] 
                                                                                                  
 mixed5 (Concatenate)           (None, 7, 7, 768)    0           ['activation_40[0][0]',          
                                                                  'activation_43[0][0]',          
                                                                  'activation_48[0][0]',          
                                                                  'activation_49[0][0]']          
                                                                                                  
 conv2d_60 (Conv2D)             (None, 7, 7, 160)    122880      ['mixed5[0][0]']                 
                                                                                                  
 batch_normalization_54 (BatchN  (None, 7, 7, 160)   480         ['conv2d_60[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_54 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_54[0][0]'] 
                                                                                                  
 conv2d_61 (Conv2D)             (None, 7, 7, 160)    179200      ['activation_54[0][0]']          
                                                                                                  
 batch_normalization_55 (BatchN  (None, 7, 7, 160)   480         ['conv2d_61[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_55 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_55[0][0]'] 
                                                                                                  
 conv2d_57 (Conv2D)             (None, 7, 7, 160)    122880      ['mixed5[0][0]']                 
                                                                                                  
 conv2d_62 (Conv2D)             (None, 7, 7, 160)    179200      ['activation_55[0][0]']          
                                                                                                  
 batch_normalization_51 (BatchN  (None, 7, 7, 160)   480         ['conv2d_57[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_56 (BatchN  (None, 7, 7, 160)   480         ['conv2d_62[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_51 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_51[0][0]'] 
                                                                                                  
 activation_56 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_56[0][0]'] 
                                                                                                  
 conv2d_58 (Conv2D)             (None, 7, 7, 160)    179200      ['activation_51[0][0]']          
                                                                                                  
 conv2d_63 (Conv2D)             (None, 7, 7, 160)    179200      ['activation_56[0][0]']          
                                                                                                  
 batch_normalization_52 (BatchN  (None, 7, 7, 160)   480         ['conv2d_58[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_57 (BatchN  (None, 7, 7, 160)   480         ['conv2d_63[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_52 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_52[0][0]'] 
                                                                                                  
 activation_57 (Activation)     (None, 7, 7, 160)    0           ['batch_normalization_57[0][0]'] 
                                                                                                  
 average_pooling2d_5 (AveragePo  (None, 7, 7, 768)   0           ['mixed5[0][0]']                 
 oling2D)                                                                                         
                                                                                                  
 conv2d_56 (Conv2D)             (None, 7, 7, 192)    147456      ['mixed5[0][0]']                 
                                                                                                  
 conv2d_59 (Conv2D)             (None, 7, 7, 192)    215040      ['activation_52[0][0]']          
                                                                                                  
 conv2d_64 (Conv2D)             (None, 7, 7, 192)    215040      ['activation_57[0][0]']          
                                                                                                  
 conv2d_65 (Conv2D)             (None, 7, 7, 192)    147456      ['average_pooling2d_5[0][0]']    
                                                                                                  
 batch_normalization_50 (BatchN  (None, 7, 7, 192)   576         ['conv2d_56[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_53 (BatchN  (None, 7, 7, 192)   576         ['conv2d_59[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_58 (BatchN  (None, 7, 7, 192)   576         ['conv2d_64[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_59 (BatchN  (None, 7, 7, 192)   576         ['conv2d_65[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_50 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_50[0][0]'] 
                                                                                                  
 activation_53 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_53[0][0]'] 
                                                                                                  
 activation_58 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_58[0][0]'] 
                                                                                                  
 activation_59 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_59[0][0]'] 
                                                                                                  
 mixed6 (Concatenate)           (None, 7, 7, 768)    0           ['activation_50[0][0]',          
                                                                  'activation_53[0][0]',          
                                                                  'activation_58[0][0]',          
                                                                  'activation_59[0][0]']          
                                                                                                  
 conv2d_70 (Conv2D)             (None, 7, 7, 192)    147456      ['mixed6[0][0]']                 
                                                                                                  
 batch_normalization_64 (BatchN  (None, 7, 7, 192)   576         ['conv2d_70[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_64 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_64[0][0]'] 
                                                                                                  
 conv2d_71 (Conv2D)             (None, 7, 7, 192)    258048      ['activation_64[0][0]']          
                                                                                                  
 batch_normalization_65 (BatchN  (None, 7, 7, 192)   576         ['conv2d_71[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_65 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_65[0][0]'] 
                                                                                                  
 conv2d_67 (Conv2D)             (None, 7, 7, 192)    147456      ['mixed6[0][0]']                 
                                                                                                  
 conv2d_72 (Conv2D)             (None, 7, 7, 192)    258048      ['activation_65[0][0]']          
                                                                                                  
 batch_normalization_61 (BatchN  (None, 7, 7, 192)   576         ['conv2d_67[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_66 (BatchN  (None, 7, 7, 192)   576         ['conv2d_72[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_61 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_61[0][0]'] 
                                                                                                  
 activation_66 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_66[0][0]'] 
                                                                                                  
 conv2d_68 (Conv2D)             (None, 7, 7, 192)    258048      ['activation_61[0][0]']          
                                                                                                  
 conv2d_73 (Conv2D)             (None, 7, 7, 192)    258048      ['activation_66[0][0]']          
                                                                                                  
 batch_normalization_62 (BatchN  (None, 7, 7, 192)   576         ['conv2d_68[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_67 (BatchN  (None, 7, 7, 192)   576         ['conv2d_73[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_62 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_62[0][0]'] 
                                                                                                  
 activation_67 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_67[0][0]'] 
                                                                                                  
 average_pooling2d_6 (AveragePo  (None, 7, 7, 768)   0           ['mixed6[0][0]']                 
 oling2D)                                                                                         
                                                                                                  
 conv2d_66 (Conv2D)             (None, 7, 7, 192)    147456      ['mixed6[0][0]']                 
                                                                                                  
 conv2d_69 (Conv2D)             (None, 7, 7, 192)    258048      ['activation_62[0][0]']          
                                                                                                  
 conv2d_74 (Conv2D)             (None, 7, 7, 192)    258048      ['activation_67[0][0]']          
                                                                                                  
 conv2d_75 (Conv2D)             (None, 7, 7, 192)    147456      ['average_pooling2d_6[0][0]']    
                                                                                                  
 batch_normalization_60 (BatchN  (None, 7, 7, 192)   576         ['conv2d_66[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_63 (BatchN  (None, 7, 7, 192)   576         ['conv2d_69[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_68 (BatchN  (None, 7, 7, 192)   576         ['conv2d_74[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 batch_normalization_69 (BatchN  (None, 7, 7, 192)   576         ['conv2d_75[0][0]']              
 ormalization)                                                                                    
                                                                                                  
 activation_60 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_60[0][0]'] 
                                                                                                  
 activation_63 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_63[0][0]'] 
                                                                                                  
 activation_68 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_68[0][0]'] 
                                                                                                  
 activation_69 (Activation)     (None, 7, 7, 192)    0           ['batch_normalization_69[0][0]'] 
                                                                                                  
 mixed7 (Concatenate)           (None, 7, 7, 768)    0           ['activation_60[0][0]',          
                                                                  'activation_63[0][0]',          
                                                                  'activation_68[0][0]',          
                                                                  'activation_69[0][0]']          
                                                                                                  
 flatten (Flatten)              (None, 37632)        0           ['mixed7[0][0]']                 
                                                                                                  
 batch_normalization_94 (BatchN  (None, 37632)       150528      ['flatten[0][0]']                
 ormalization)                                                                                    
                                                                                                  
 dense_2 (Dense)                (None, 1024)         38536192    ['batch_normalization_94[0][0]'] 
                                                                                                  
 dropout (Dropout)              (None, 1024)         0           ['dense_2[0][0]']                
                                                                                                  
 dense_3 (Dense)                (None, 2)            2050        ['dropout[0][0]']                
                                                                                                  
==================================================================================================
Total params: 47,664,034
Trainable params: 38,613,506
Non-trainable params: 9,050,528
__________________________________________________________________________________________________
In [40]:
def scheduler(epoch, lr):
    
    if epoch < 20:
        return lr
    else:
        return lr * tf.math.exp(-0.2)
    
callback = tf.keras.callbacks.LearningRateScheduler(scheduler) # set the callback to our scheduler function
In [41]:
# Set the training parameters
model.compile(optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.0001), 
              loss = 'sparse_categorical_crossentropy', 
              metrics = ['accuracy'])
In [42]:
history = model.fit(
            train_generator,
            validation_data = validation_generator,
            epochs = 5,callbacks=[callback])
Epoch 1/5
 55/352 [===>..........................] - ETA: 8:21 - loss: 0.4713 - accuracy: 0.8797
C:\Users\alasmar\AppData\Local\Programs\Python\Python310\lib\site-packages\PIL\TiffImagePlugin.py:845: UserWarning:

Truncated File Read

352/352 [==============================] - 631s 2s/step - loss: 0.3665 - accuracy: 0.9112 - val_loss: 0.1978 - val_accuracy: 0.9564 - lr: 1.0000e-04
Epoch 2/5
352/352 [==============================] - 610s 2s/step - loss: 0.2878 - accuracy: 0.9269 - val_loss: 0.2882 - val_accuracy: 0.9496 - lr: 1.0000e-04
Epoch 3/5
352/352 [==============================] - 590s 2s/step - loss: 0.2395 - accuracy: 0.9344 - val_loss: 0.2465 - val_accuracy: 0.9584 - lr: 1.0000e-04
Epoch 4/5
352/352 [==============================] - 577s 2s/step - loss: 0.2146 - accuracy: 0.9404 - val_loss: 0.2291 - val_accuracy: 0.9608 - lr: 1.0000e-04
Epoch 5/5
352/352 [==============================] - 594s 2s/step - loss: 0.1820 - accuracy: 0.9430 - val_loss: 0.2573 - val_accuracy: 0.9708 - lr: 1.0000e-04

Evaluation¶

View predictions¶

In [43]:
plot_prediction(validation_generator, 10)
2/2 [==============================] - 2s 434ms/step

View saliency map¶

Saliency activation maps is used to find which parts the model was paying attention to while classifying the image¶
In [44]:
images, labels =  validation_generator.next()
In [45]:
def calculate_gradients(images, labels, index):
    """
    Computes gradient of the loss with respect to the input image
    
    Args:
    Images: numpy array containing images of shape (n,150,150,3)
    labels: numpy array containing labels shape(n,)
    index: index of the image
    """
    # get image of the given index and add 1 to it's first dimension
    image = np.expand_dims(images[index],axis=0)
    #convert image to tensor
    image_tensor = tf.convert_to_tensor(image)
    # get the class of the given label and convert it to an integer
    class_index = int(labels[index])
    # one hot encode the labels 
    true_value = tf.one_hot([class_index] * image.shape[0], 2)

    # compute the gradient of the loss
    with tf.GradientTape() as tape:
        # Watch the input image
        tape.watch(image_tensor)
        # Generate predictions
        pred  = model(image_tensor)
        # Compute loss
        loss = tf.keras.losses.categorical_crossentropy(true_value, pred)
    # Get the gradient with respect to the image
    gradients = tape.gradient(loss, image_tensor)
    
    grey_scale_gradients = tf.reduce_sum(tf.abs(gradients),axis=-1)
    normalized_gradients = (255*(grey_scale_gradients - tf.reduce_min(grey_scale_gradients))/
                           (tf.reduce_max(grey_scale_gradients) - tf.reduce_min(grey_scale_gradients)))
    
    normalized_gradients = tf.squeeze(normalized_gradients)
    normalized_gradients = tf.cast(normalized_gradients, tf.uint8)
    return normalized_gradients,pred
In [46]:
def show_saliency(images, labels, n_images):
    """
    plot saliency maps
    Args:
    Images: numpy array containing images of shape (n,150,150,3)
    labels: numpy array containing labels shape(n,)
    n_images: number of images to plot
    """
    # Loop for number of images specified
    for i in range(n_images):
        # Computes gradient of the loss with respect to the input image
        gradients,prediction = calculate_gradients(images, labels, i)
        prediction = np.argmax(prediction)
        # Colorize greyscale gradients
        gradient_color = cv2.applyColorMap(gradients.numpy(), cv2.COLORMAP_HOT)
        #Normalize the colored gradients
        gradient_color = gradient_color / 255.0
        # Super impose colored gradients on the image
        super_imposed = cv2.addWeighted(images[i], 0.6, gradient_color, 0.5, 0.1, dtype = cv2.CV_64F)
        print('Predicted Class: ' +str(class_names[prediction]+",\t"+ f'True Class: {class_names[int(labels[i])]}'))
        plt.figure(figsize=(8, 8))
        plt.imshow(super_imposed)
        plt.axis('off')
        plt.show()
In [47]:
show_saliency(images, labels, 5)
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Predicted Class: Dog,	True Class: Dog
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Predicted Class: Cat,	True Class: Cat
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Predicted Class: Cat,	True Class: Cat
Predicted Class: Dog,	True Class: Dog
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Predicted Class: Cat,	True Class: Cat

View training process¶

In [48]:
results = pd.DataFrame(history.history)
results.tail()
Out[48]:
loss accuracy val_loss val_accuracy lr
0 0.366455 0.911237 0.197829 0.9564 0.0001
1 0.287796 0.926927 0.288203 0.9496 0.0001
2 0.239462 0.934439 0.246468 0.9584 0.0001
3 0.214561 0.940395 0.229127 0.9608 0.0001
4 0.182025 0.942973 0.257326 0.9708 0.0001
In [49]:
fig = px.line(results,y=[results['accuracy'],results['val_accuracy']],template="plotly_dark",color_discrete_sequence=['#F67280','#DD2706'])
fig.update_layout(   
    title_font_color="#41BEE9", 
    xaxis=dict(color="#41BEE9",title='Epochs'), 
    yaxis=dict(color="#41BEE9")
 )
fig.show()
In [50]:
fig = px.line(results,y=[results['loss'],results['val_loss']],template="plotly_dark",color_discrete_sequence=['#F67280','#DD2706'])
fig.update_layout(   
    title_font_color="#41BEE9", 
    xaxis=dict(color="#41BEE9",title='Epochs'), 
    yaxis=dict(color="#41BEE9")
 )
fig.show()

Conclusion¶

We were able to achieve 94 training accuracy and 97 validation accuracy¶
This seems much better than the original results from the simple CNN¶